﻿using System;
using System.IO;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using VioletDevelopmentLaboratory.Net.Web.Component;

namespace VioletDevelopmentLaboratory.Net.Web.WebControls
{
	public class CellTemplateContainer : Control, INamingContainer
	{
		private UploadFileInfo currentUploadFileInfo;
		public UploadFileInfo CurrentUploadFileInfo
		{
			get { return currentUploadFileInfo; }
		}

		internal CellTemplateContainer(UploadFileInfo currentUploadFileInfo)
		{
			this.currentUploadFileInfo = currentUploadFileInfo;
		}
	}

	#region MultiFileUploadHelper Event
	public delegate void MultiFileUploadHelperAddEventHandler(Object sender, MultiFileUploadHelperAddEventArgs e);
	public class MultiFileUploadHelperAddEventArgs : EventArgs
	{
		public MultiFileUploadHelperAddEventArgs()
		{
			cancel = false;
		}

		private Boolean cancel;
		public Boolean Cancel { get { return cancel; } set { cancel = value; } }

		private UploadFileInfo newUploadFileInfo;
		public UploadFileInfo NewUploadFileInfo { get { return newUploadFileInfo; } set { newUploadFileInfo = value; } }

		private HttpPostedFile postedFile;
		public HttpPostedFile PostedFile { get { return postedFile; } internal set { postedFile = value; } }

		private String description;
		public String Description { get { return description; } internal set { description = value; } }
	}

	public delegate void MultiFileUploadHelperAddedEventHandler(object sender, MultiFileUploadHelperAddedEventArgs e);
	public class MultiFileUploadHelperAddedEventArgs : EventArgs
	{
		public MultiFileUploadHelperAddedEventArgs()
		{
			exception = null;
		}

		private Exception exception;
		public Exception Exception { get { return exception; } internal set { exception = value; } }
	}

	public delegate void MultiFileUploadHelperRemoveEventHandler(object sender, MultiFileUploadHelperRemoveEventArgs e);
	public class MultiFileUploadHelperRemoveEventArgs : EventArgs
	{
		public MultiFileUploadHelperRemoveEventArgs()
		{
			cancel = false;
		}

		private Boolean cancel;
		public Boolean Cancel { get { return cancel; } set { cancel = value; } }

		private UploadFileInfo removeUploadFileInfo;
		public UploadFileInfo RemoveUploadFileInfo { get { return removeUploadFileInfo; } internal set { removeUploadFileInfo = value; } }
	}

	public delegate void MultiFileUploadHelperRemovedEventHandler(object sender, MultiFileUploadHelperRemovedEventArgs e);
	public class MultiFileUploadHelperRemovedEventArgs : EventArgs
	{
		public MultiFileUploadHelperRemovedEventArgs()
		{
			exception = null;
		}

		private Exception exception;
		public Exception Exception { get { return exception; } internal set { exception = value; } }
	}

	public delegate void MultiFileUploadHelperRowCreatedEventHandler(object sender, MultiFileUploadHelperRowCreatedEventArgs e);
	public class MultiFileUploadHelperRowCreatedEventArgs : EventArgs
	{
		public MultiFileUploadHelperRowCreatedEventArgs(CellTemplateContainer previewCellTemplate,
			CellTemplateContainer infoCellTemplate, CellTemplateContainer lengthCellTemplate,
			UploadFileInfo currentUploadFileInfo)
		{
			this.previewCellTemplate = previewCellTemplate;
			this.infoCellTemplate = infoCellTemplate;
			this.lengthCellTemplate = lengthCellTemplate;
			this.currentUploadFileInfo = currentUploadFileInfo;
		}

		private CellTemplateContainer previewCellTemplate;
		public CellTemplateContainer PreviewCellTemplate { get { return previewCellTemplate; } }

		private CellTemplateContainer infoCellTemplate;
		public CellTemplateContainer InfoCellTemplate { get { return infoCellTemplate; } }

		private CellTemplateContainer lengthCellTemplate;
		public CellTemplateContainer LengthCellTemplate { get { return lengthCellTemplate; } }

		private UploadFileInfo currentUploadFileInfo;
		public UploadFileInfo CurrentUploadFileInfo { get { return currentUploadFileInfo; } }
	}
	#endregion

	[ToolboxData("<{0}:MultiFileUploadHelper runat=server></{0}:MultiFileUploadHelper>"),
	ParseChildren(ChildrenAsProperties = true),
	Designer(typeof(VWebControlDesigner))]
	public class MultiFileUploadHelper : Control, INamingContainer
	{
		[Browsable(false)]
		public UploadFileInfoCollection CurrentUploadFileInfoCollection
		{
			get { return (UploadFileInfoCollection)ViewState["UploadFileInfoCollection"]; }
			set { ViewState["UploadFileInfoCollection"] = value; }
		}

		#region Behavior
		[Browsable(true), Category("Behavior"), DefaultValue(1)]
		public Int32 UploadLimit { get { return (Int32)ViewState["UploadLimit"]; } set { ViewState["UploadLimit"] = value; } }

		[Browsable(true), Category("Behavior"), DefaultValue(2048)]
		public Int32 UploadSizeLimit { get { return (Int32)ViewState["UploadSizeLimit"]; } set { ViewState["UploadSizeLimit"] = value; } }

		[Browsable(true), Category("Behavior"), DefaultValue("gif;jpg;jpeg;png;zip")]
		public String UploadExtensions { get { return ViewState["UploadExtensions"].ToString(); } set { ViewState["UploadExtensions"] = value; } }

		[Browsable(false), Category("Behavior"), DefaultValue(false)]
		public Boolean CurrentUserIsAdministrator { get { return (Boolean)ViewState["CurrentUserIsAdministrator"]; } set { ViewState["CurrentUserIsAdministrator"] = value; } }

		[Browsable(true), Category("Behavior"), DefaultValue(""), Description("클라이언트측 OnAddClick에 대해 실행할 클라이언트측 스크립트입니다.")]
		public String OnClientAddClick { get { return ViewState["OnClientAddClick"].ToString(); } set { ViewState["OnClientAddClick"] = value; } }

		[Browsable(true), Category("Behavior"), DefaultValue(""), Description("클라이언트측 OnRemoveClick에 대해 실행할 클라이언트측 스크립트입니다.")]
		public String OnClientRemoveClick { get { return ViewState["OnClientRemoveClick"].ToString(); } set { ViewState["OnClientRemoveClick"] = value; } }
		#endregion

		#region Preview ImageUrl Appearance
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String CommonFileImageUrl { get { return ViewState["CommonFileImageUrl"].ToString(); } set { ViewState["CommonFileImageUrl"] = value; } }

		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String ImageFileImageUrl { get { return ViewState["ImageFileImageUrl"].ToString(); } set { ViewState["ImageFileImageUrl"] = value; } }

		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String VideoFileImageUrl { get { return ViewState["VideoFileImageUrl"].ToString(); } set { ViewState["VideoFileImageUrl"] = value; } }

		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String AudioFileImageUrl { get { return ViewState["AudioFileImageUrl"].ToString(); } set { ViewState["AudioFileImageUrl"] = value; } }

		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String FlashFileImageUrl { get { return ViewState["FlashFileImageUrl"].ToString(); } set { ViewState["FlashFileImageUrl"] = value; } }
		#endregion

		#region FileLabel Appearance
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String FileLabelText { get { return ViewState["FileLabelText"].ToString(); } set { ViewState["FileLabelText"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String FileLabelCssClass { get { return ViewState["FileLabelCssClass"].ToString(); } set { ViewState["FileLabelCssClass"] = value; } }
		#endregion

		#region FileUpload Appearance
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String FileUploadCssClass { get { return ViewState["FileUploadCssClass"].ToString(); } set { ViewState["FileUploadCssClass"] = value; } }
		#endregion

		#region DescriptionLabel Appearance
		[Browsable(true), Category("Appearance"), DefaultValue("Description")]
		public String DescriptionLabelText { get { return ViewState["DescriptionLabelText"].ToString(); } set { ViewState["DescriptionLabelText"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String DescriptionLabelCssClass { get { return ViewState["DescriptionLabelCssClass"].ToString(); } set { ViewState["DescriptionLabelCssClass"] = value; } }
		#endregion

		#region DescriptionTextBox Appearance
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String DescriptionTextBoxCssClass { get { return ViewState["DescriptionTextBoxCssClass"].ToString(); } set { ViewState["DescriptionTextBoxCssClass"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("10")]
		public Int32 DescriptionTextBoxColumns { get { return (Int32)ViewState["DescriptionColumns"]; } set { ViewState["DescriptionColumns"] = value; } }
		#endregion

		#region AddButton Appearance
		[Browsable(true), Category("Appearance"), DefaultValue("Add")]
		public String AddButtonText { get { return ViewState["AddButtonText"].ToString(); } set { ViewState["AddButtonText"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String AddButtonImageUrl { get { return ViewState["AddButtonImageUrl"].ToString(); } set { ViewState["AddButtonImageUrl"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String AddButtonCssClass { get { return ViewState["AddButtonCssClass"].ToString(); } set { ViewState["AddButtonCssClass"] = value; } }
		#endregion

		#region RemoveButton Appearance
		[Browsable(true), Category("Appearance"), DefaultValue("Remove")]
		public String RemoveButtonText { get { return ViewState["RemoveButtonText"].ToString(); } set { ViewState["RemoveButtonText"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String RemoveButtonImageUrl { get { return ViewState["RemoveButtonImageUrl"].ToString(); } set { ViewState["RemoveButtonImageUrl"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String RemoveButtonCssClass { get { return ViewState["RemoveButtonCssClass"].ToString(); } set { ViewState["RemoveButtonCssClass"] = value; } }
		#endregion

		#region Rule Appearance
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String RuleMessage { get { return ViewState["RuleMessage"].ToString(); } set { ViewState["RuleMessage"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String RuleCssClass { get { return ViewState["RuleCssClass"].ToString(); } set { ViewState["RuleCssClass"] = value; } }
		#endregion

		#region FileTable Appearance
		[Browsable(true), Category("Appearance"), DefaultValue("0")]
		public Int32 ListCellspacing { get { return (Int32)ViewState["FileListCellspacing"]; } set { ViewState["FileListCellspacing"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("0")]
		public Int32 ListCellpadding { get { return (Int32)ViewState["ListCellpadding"]; } set { ViewState["ListCellpadding"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String ListCssClass { get { return ViewState["ListCssClass"].ToString(); } set { ViewState["ListCssClass"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String ListRowCssClass { get { return ViewState["ListRowCssClass"].ToString(); } set { ViewState["ListRowCssClass"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String ListPreviewCellCssClass { get { return ViewState["ListPreviewCellCssClass"].ToString(); } set { ViewState["ListPreviewCellCssClass"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String ListFileInfoCellCssClass { get { return ViewState["ListFileInfoCellCssClass"].ToString(); } set { ViewState["ListFileInfoCellCssClass"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String ListFileLengthCellCssClass { get { return ViewState["ListFileLengthCellCssClass"].ToString(); } set { ViewState["ListFileLengthCellCssClass"] = value; } }
		[Browsable(true), Category("Appearance"), DefaultValue("")]
		public String ListCommandCellCssClass { get { return ViewState["ListCommandCellCssClass"].ToString(); } set { ViewState["ListCommandCellCssClass"] = value; } }
		#endregion

		private Panel uploadFormPanel;
		private FileUpload fileUpload;
		private TextBox descriptionTextBox;
		private Table fileTable;
		private TableRow fileTableRow;
		private TableCell fileTableCell;

		public MultiFileUploadHelper()
		{
			this.EnableViewState = true;

			CurrentUploadFileInfoCollection = new UploadFileInfoCollection();

			this.UploadLimit = 1;
			this.UploadSizeLimit = 2048;
			this.UploadExtensions = "gif;jpg;png;zip";
			this.CurrentUserIsAdministrator = false;
			this.OnClientAddClick = "";
			this.OnClientRemoveClick = "";

			this.CommonFileImageUrl = "";
			this.ImageFileImageUrl = "";
			this.VideoFileImageUrl = "";
			this.AudioFileImageUrl = "";
			this.FlashFileImageUrl = "";

			this.FileLabelText = "";
			this.FileLabelCssClass = "";

			this.FileUploadCssClass = "";

			this.DescriptionLabelText = "";
			this.DescriptionLabelCssClass = "";

			this.DescriptionTextBoxColumns = 0;
			this.DescriptionTextBoxCssClass = "";

			this.AddButtonText = "";
			this.AddButtonImageUrl = "";
			this.AddButtonCssClass = "";

			this.RemoveButtonText = "";
			this.RemoveButtonImageUrl = "";
			this.RemoveButtonCssClass = "";

			this.RuleMessage = "";
			this.RuleCssClass = "";

			this.ListCellspacing = 0;
			this.ListCellpadding = 0;
			this.ListCssClass = "";
			this.ListRowCssClass = "";
			this.ListPreviewCellCssClass = "";
			this.ListFileInfoCellCssClass = "";
			this.ListFileLengthCellCssClass = "";
			this.ListCommandCellCssClass = "";

			uploadFormPanel = new Panel();
			uploadFormPanel.EnableViewState = false;

			fileUpload = new FileUpload();
			fileUpload.EnableViewState = false;

			descriptionTextBox = new TextBox();
			descriptionTextBox.EnableViewState = false;

			fileTable = new Table();
			fileTable.EnableViewState = false;
		}

		#region Event
		[Category("Action")]
		public event MultiFileUploadHelperAddEventHandler FileAdding;
		[Category("Action")]
		public event MultiFileUploadHelperAddedEventHandler FileAdded;
		[Category("Action")]
		public event MultiFileUploadHelperRemoveEventHandler FileRemoving;
		[Category("Action")]
		public event MultiFileUploadHelperRemovedEventHandler FileRemoved;
		[Category("Action")]
		public event MultiFileUploadHelperRowCreatedEventHandler RowCreated;

		private void onAddEvent(String commandArgument)
		{
			MultiFileUploadHelperAddEventArgs addEventArgs = new MultiFileUploadHelperAddEventArgs();

			if (FileAdding != null)
			{
				addEventArgs.PostedFile = fileUpload.PostedFile;
				addEventArgs.Description = descriptionTextBox.Text;
				descriptionTextBox.Text = "";
				FileAdding(this, addEventArgs);
			}

			if (!addEventArgs.Cancel)
			{
				MultiFileUploadHelperAddedEventArgs addedEventArgs = new MultiFileUploadHelperAddedEventArgs();

				try
				{
					//ViewState업데이트
					CurrentUploadFileInfoCollection.Add(addEventArgs.NewUploadFileInfo);
					ViewState["UploadFileInfoCollection"] = CurrentUploadFileInfoCollection;

					//fileTable업데이트
					this.fillTableRow(addEventArgs.NewUploadFileInfo);

					if (CurrentUploadFileInfoCollection.Count >= UploadLimit && !CurrentUserIsAdministrator)
					{
						uploadFormPanel.Visible = false;
					}
				}
				catch (System.Exception ex)
				{
					addedEventArgs.Exception = ex;
				}

				if (FileAdded != null)
				{
					FileAdded(this, addedEventArgs);
				}
			}
		}

		private void onRemoveEvent(String commandArgument)
		{
			MultiFileUploadHelperRemoveEventArgs removeEventArgs = new MultiFileUploadHelperRemoveEventArgs();

			UploadFileInfo removeFile = null;

			foreach (UploadFileInfo file in CurrentUploadFileInfoCollection)
			{
				if (file.FileID == commandArgument)
				{
					removeFile = file;
					break;
				}
			}
			removeEventArgs.RemoveUploadFileInfo = removeFile;

			if (FileRemoving != null)
			{
				FileRemoving(this, removeEventArgs);
			}

			if (!removeEventArgs.Cancel)
			{
				MultiFileUploadHelperRemovedEventArgs removedEventArgs = new MultiFileUploadHelperRemovedEventArgs();

				try
				{
					//ViewState업데이트
					CurrentUploadFileInfoCollection.Remove(removeFile);
					ViewState["UploadFileInfoCollection"] = CurrentUploadFileInfoCollection;

					//fileTable업데이트
					TableRow removeRow = null;

					foreach (TableRow row in fileTable.Rows)
					{
						IButtonControl button = (IButtonControl)row.Cells[3].Controls[0];

						if (button.CommandArgument == commandArgument)
						{
							removeRow = row;
							break;
						}
					}

					fileTable.Rows.Remove(removeRow);

					if (CurrentUploadFileInfoCollection.Count < UploadLimit)
					{
						uploadFormPanel.Visible = true;
					}
				}
				catch (System.Exception ex)
				{
					removedEventArgs.Exception = ex;
				}

				if (FileRemoved != null)
				{
					FileRemoved(this, removedEventArgs);
				}
			}
		}

		protected override bool OnBubbleEvent(Object sender, EventArgs args)
		{
			if (sender is IButtonControl)
			{
				String commandName = "", commandArgument = "";

				IButtonControl commandbutton = (IButtonControl)sender;
				commandName = commandbutton.CommandName;
				commandArgument = commandbutton.CommandArgument;

				switch (commandName)
				{
					case "Add" :
						this.onAddEvent(commandArgument);
						break;
					case "Remove" :
						this.onRemoveEvent(commandArgument);
						break;
				}
			}

			return true;
		}
		#endregion

		#region Template
		private ITemplate previewCellTemplate;
		[TemplateContainer(typeof(CellTemplateContainer)), PersistenceMode(PersistenceMode.InnerProperty), Browsable(false)]
		public ITemplate PreviewCellTemplate
		{
			get { return previewCellTemplate; }
			set { previewCellTemplate = value; }
		}

		private ITemplate infoCellTemplate;
		[TemplateContainer(typeof(CellTemplateContainer)), PersistenceMode(PersistenceMode.InnerProperty), Browsable(false)]
		public ITemplate InfoCellTemplate
		{
			get { return infoCellTemplate; }
			set { infoCellTemplate = value; }
		}

		private ITemplate lengthCellTemplate;
		[TemplateContainer(typeof(CellTemplateContainer)), PersistenceMode(PersistenceMode.InnerProperty), Browsable(false)]
		public ITemplate LengthCellTemplate
		{
			get { return lengthCellTemplate; }
			set { lengthCellTemplate = value; }
		}

		private TableCell createPreviewCell(UploadFileInfo uploadFileInfo, out CellTemplateContainer template)
		{
			template = null;
			fileTableCell = new TableCell();
			fileTableCell.EnableViewState = false;

			if (PreviewCellTemplate != null)
			{
				//템플릿 로드
				template = new CellTemplateContainer(uploadFileInfo);
				template.EnableViewState = false;
				PreviewCellTemplate.InstantiateIn(template);

				fileTableCell.CssClass = this.ListPreviewCellCssClass;
				fileTableCell.Controls.Add(template);
				fileTableCell.DataBind();
			}
			else
			{
				//기본값
				Image iconImage = new Image();
				iconImage.EnableViewState = false;

				if (uploadFileInfo.ContentType.IndexOf("image") > -1)
				{
					iconImage.AlternateText = "Image";
					iconImage.ImageUrl = this.ImageFileImageUrl;
				}
				else if (uploadFileInfo.ContentType.IndexOf("video") > -1)
				{
					iconImage.AlternateText = "Video";
					iconImage.ImageUrl = this.VideoFileImageUrl;
				}
				else if (uploadFileInfo.ContentType.IndexOf("audio") > -1)
				{
					iconImage.AlternateText = "Audio";
					iconImage.ImageUrl = this.AudioFileImageUrl;
				}
				else if (uploadFileInfo.ContentType.IndexOf("flash") > -1)
				{
					iconImage.AlternateText = "Flash";
					iconImage.ImageUrl = this.FlashFileImageUrl;
				}
				else
				{
					iconImage.AlternateText = "File";
					iconImage.ImageUrl = this.CommonFileImageUrl;
				}

				fileTableCell.CssClass = this.ListPreviewCellCssClass;
				fileTableCell.Controls.Add(iconImage);
			}

			return fileTableCell;
		}

		private TableCell createInfoCell(UploadFileInfo uploadFileInfo, out CellTemplateContainer template)
		{
			template = null;
			fileTableCell = new TableCell();
			fileTableCell.EnableViewState = false;

			if (infoCellTemplate != null)
			{
				//템플릿 로드
				template = new CellTemplateContainer(uploadFileInfo);
				template.EnableViewState = false;
				InfoCellTemplate.InstantiateIn(template);

				fileTableCell.CssClass = this.ListFileInfoCellCssClass;
				fileTableCell.Controls.Add(template);
				fileTableCell.DataBind();
			}
			else
			{
				fileTableCell.CssClass = this.ListFileInfoCellCssClass;
				fileTableCell.Text = uploadFileInfo.OriginalFileName + "<br />Type : " + uploadFileInfo.ContentType + "<br />Description : " + uploadFileInfo.Description;
			}

			return fileTableCell;
		}

		private TableCell createLengthCell(UploadFileInfo uploadFileInfo, out CellTemplateContainer template)
		{
			template = null;
			fileTableCell = new TableCell();
			fileTableCell.EnableViewState = false;

			if (lengthCellTemplate != null)
			{
				//템플릿 로드
				template = new CellTemplateContainer(uploadFileInfo);
				template.EnableViewState = false;
				LengthCellTemplate.InstantiateIn(template);

				fileTableCell.CssClass = this.ListFileLengthCellCssClass;
				fileTableCell.Controls.Add(template);
				fileTableCell.DataBind();
			}
			else
			{
				fileTableCell.CssClass = this.ListFileLengthCellCssClass;
				fileTableCell.Text = VUtility.GetFormatFileLength(uploadFileInfo.ContentLength);
			}

			return fileTableCell;
		}
		#endregion

		#region FileTable
		private void fillTableRow(UploadFileInfo uploadFileInfo)
		{
			fileTableRow = new TableRow();
			fileTableRow.EnableViewState = false;
			fileTableRow.CssClass = this.ListRowCssClass;

			CellTemplateContainer previewCellTemplateContainer;
			fileTableRow.Cells.Add(createPreviewCell(uploadFileInfo, out previewCellTemplateContainer));

			CellTemplateContainer infoCellTemplateContainer;
			fileTableRow.Cells.Add(createInfoCell(uploadFileInfo, out infoCellTemplateContainer));

			CellTemplateContainer lengthCellTemplateContainer;
			fileTableRow.Cells.Add(createLengthCell(uploadFileInfo, out lengthCellTemplateContainer));

			fileTableCell = new TableCell();
			fileTableCell.EnableViewState = false;
			fileTableCell.CssClass = ListCommandCellCssClass;

			if (String.IsNullOrEmpty(this.RemoveButtonImageUrl))
			{
				Button removeButton = new Button();
				removeButton.EnableViewState = false;
				removeButton.Text = this.RemoveButtonText;
				removeButton.CssClass = this.RemoveButtonCssClass;
				removeButton.ID = "RemoveButton_" + uploadFileInfo.FileID;
				removeButton.CommandName = "Remove";
				removeButton.CommandArgument = uploadFileInfo.FileID;
				removeButton.CausesValidation = false;
				removeButton.OnClientClick = this.OnClientRemoveClick;

				fileTableCell.Controls.Add(removeButton);
			}
			else
			{
				LinkButton removeButton = new LinkButton();
				removeButton.EnableViewState = false;
				removeButton.Text = this.RemoveButtonText;
				removeButton.CssClass = this.RemoveButtonCssClass;
				removeButton.ID = "RemoveButton_" + uploadFileInfo.FileID;
				removeButton.CommandName = "Remove";
				removeButton.CommandArgument = uploadFileInfo.FileID;
				removeButton.CausesValidation = false;
				removeButton.OnClientClick = this.OnClientRemoveClick;

				Image removeImage = new Image();
				removeImage.EnableViewState = false;
				removeImage.ImageAlign = ImageAlign.Top;
				removeImage.ImageUrl = this.RemoveButtonImageUrl;
				removeImage.AlternateText = this.RemoveButtonText;

				removeButton.Controls.Add(removeImage);

				fileTableCell.Controls.Add(removeButton);
			}
			fileTableRow.Cells.Add(fileTableCell);

			fileTable.Rows.Add(fileTableRow);

			MultiFileUploadHelperRowCreatedEventArgs rowCreatedEventArgs = new MultiFileUploadHelperRowCreatedEventArgs(
				previewCellTemplateContainer, infoCellTemplateContainer, lengthCellTemplateContainer, uploadFileInfo);
			if (RowCreated != null)
			{
				RowCreated(this, rowCreatedEventArgs);
			}
		}

		private void fileTableBind()
		{
			foreach (UploadFileInfo file in CurrentUploadFileInfoCollection)
			{
				this.fillTableRow(file);
			}
		}
		#endregion

		protected override void CreateChildControls()
		{
			this.CommonFileImageUrl = VUtility.GetControlSetting(this.CommonFileImageUrl, "MultiFileUploadHelper.CommonFileImageUrl", "");
			this.ImageFileImageUrl = VUtility.GetControlSetting(this.ImageFileImageUrl, "MultiFileUploadHelper.ImageFileImageUrl", "");
			this.VideoFileImageUrl = VUtility.GetControlSetting(this.VideoFileImageUrl, "MultiFileUploadHelper.VideoFileImageUrl", "");
			this.AudioFileImageUrl = VUtility.GetControlSetting(this.AudioFileImageUrl, "MultiFileUploadHelper.AudioFileImageUrl", "");
			this.FlashFileImageUrl = VUtility.GetControlSetting(this.FlashFileImageUrl, "MultiFileUploadHelper.FlashFileImageUrl", "");

			this.FileLabelText = VUtility.GetControlSetting(this.FileLabelText, "MultiFileUploadHelper.FileLabelText", "");
			this.FileLabelCssClass = VUtility.GetControlSetting(this.FileLabelCssClass, "MultiFileUploadHelper.FileLabelCssClass", "");

			this.FileUploadCssClass = VUtility.GetControlSetting(this.FileUploadCssClass, "MultiFileUploadHelper.FileUploadCssClass", "");

			this.DescriptionLabelText = VUtility.GetControlSetting(this.DescriptionLabelText, "MultiFileUploadHelper.DescriptionLabelText", "Description");
			this.DescriptionLabelCssClass = VUtility.GetControlSetting(this.DescriptionLabelCssClass, "MultiFileUploadHelper.DescriptionLabelCssClass", "");

			this.DescriptionTextBoxColumns = VUtility.GetControlSetting(5, 30, this.DescriptionTextBoxColumns, "MultiFileUploadHelper.DescriptionTextBoxColumns", 10);
			this.DescriptionTextBoxCssClass = VUtility.GetControlSetting(this.DescriptionTextBoxCssClass, "MultiFileUploadHelper.DescriptionTextBoxCssClass", "");

			this.AddButtonText = VUtility.GetControlSetting(this.AddButtonText, "MultiFileUploadHelper.AddButtonText", "Add");
			this.AddButtonImageUrl = VUtility.GetControlSetting(this.AddButtonImageUrl, "MultiFileUploadHelper.AddButtonImageUrl", "");
			this.AddButtonCssClass = VUtility.GetControlSetting(this.AddButtonCssClass, "MultiFileUploadHelper.AddButtonCssClass", "");

			this.RemoveButtonText = VUtility.GetControlSetting(this.RemoveButtonText, "MultiFileUploadHelper.RemoveButtonText", "Remove");
			this.RemoveButtonImageUrl = VUtility.GetControlSetting(this.RemoveButtonImageUrl, "MultiFileUploadHelper.RemoveButtonImageUrl", "");
			this.RemoveButtonCssClass = VUtility.GetControlSetting(this.RemoveButtonCssClass, "MultiFileUploadHelper.RemoveButtonCssClass", "");

			this.RuleMessage = VUtility.GetControlSetting(this.RuleMessage, "MultiFileUploadHelper.RuleMessage", "");
			this.RuleCssClass = VUtility.GetControlSetting(this.RuleCssClass, "MultiFileUploadHelper.RuleCssClass", "");

			this.ListCellspacing = VUtility.GetControlSetting(0, 20, this.ListCellspacing, "MultiFileUploadHelper.ListCellspacing", 0);
			this.ListCellpadding = VUtility.GetControlSetting(0, 20, this.ListCellpadding, "MultiFileUploadHelper.ListCellpadding", 0); ;
			this.ListCssClass = VUtility.GetControlSetting(this.ListCssClass, "MultiFileUploadHelper.ListCssClass", "");
			this.ListRowCssClass = VUtility.GetControlSetting(this.ListRowCssClass, "MultiFileUploadHelper.ListRowCssClass", "");
			this.ListPreviewCellCssClass = VUtility.GetControlSetting(this.ListPreviewCellCssClass, "MultiFileUploadHelper.ListPreviewCellCssClass", "");
			this.ListFileInfoCellCssClass = VUtility.GetControlSetting(this.ListFileInfoCellCssClass, "MultiFileUploadHelper.ListFileInfoCellCssClass", "");
			this.ListFileLengthCellCssClass = VUtility.GetControlSetting(this.ListFileLengthCellCssClass, "MultiFileUploadHelper.ListFileLengthCellCssClass", "");
			this.ListCommandCellCssClass = VUtility.GetControlSetting(this.ListCommandCellCssClass, "MultiFileUploadHelper.ListCommandCellCssClass", "");


			fileUpload.CssClass = this.FileUploadCssClass;
			descriptionTextBox.CssClass = this.DescriptionTextBoxCssClass;
			descriptionTextBox.Columns = this.DescriptionTextBoxColumns;
			descriptionTextBox.MaxLength = 100;


			this.Controls.Clear();

			#region RuleMessage
			Literal ruleLiteral = new Literal();
			ruleLiteral.EnableViewState = false;
			ruleLiteral.Text = "<div class=\"" + this.RuleCssClass + "\">" + this.RuleMessage + "</div>";

			this.Controls.Add(ruleLiteral);
			#endregion

			#region UploadForm
			if ((CurrentUploadFileInfoCollection.Count >= this.UploadLimit) && !CurrentUserIsAdministrator)
			{
				uploadFormPanel.Visible = false;
			}

			Label fileLabel = new Label();
			fileLabel.EnableViewState = false;
			fileLabel.Text = this.FileLabelText;
			fileLabel.CssClass = this.FileLabelCssClass;

			fileUpload.CssClass = this.DescriptionTextBoxCssClass;

			uploadFormPanel.Controls.Add(fileLabel);
			uploadFormPanel.Controls.Add(fileUpload);

			Label descriptionLabel = new Label();
			descriptionLabel.EnableViewState = false;
			descriptionLabel.Text = this.DescriptionLabelText;
			descriptionLabel.CssClass = this.DescriptionLabelCssClass;

			descriptionTextBox.Columns = this.DescriptionTextBoxColumns;
			descriptionTextBox.CssClass = this.DescriptionTextBoxCssClass;

			uploadFormPanel.Controls.Add(descriptionLabel);
			uploadFormPanel.Controls.Add(descriptionTextBox);

			if (String.IsNullOrEmpty(this.AddButtonImageUrl))
			{
				Button addButton = new Button();
				addButton.EnableViewState = false;
				addButton.Text = this.AddButtonText;
				addButton.CssClass = this.AddButtonCssClass;
				addButton.CommandName = "Add";
				addButton.CausesValidation = false;
				addButton.OnClientClick = this.OnClientAddClick;

				uploadFormPanel.Controls.Add(addButton);
			}
			else
			{
				LinkButton addButton = new LinkButton();
				addButton.EnableViewState = false;
				addButton.Text = this.AddButtonText;
				addButton.CssClass = this.AddButtonCssClass;
				addButton.CommandName = "Add";
				addButton.CausesValidation = false;
				addButton.OnClientClick = this.OnClientAddClick;

				Image addImage = new Image();
				addImage.EnableViewState = false;
				addImage.ImageAlign = ImageAlign.Top;
				addImage.ImageUrl = this.AddButtonImageUrl;
				addImage.AlternateText = this.AddButtonText;

				addButton.Controls.Add(addImage);

				uploadFormPanel.Controls.Add(addButton);
			}

			this.Controls.Add(uploadFormPanel);
			#endregion

			#region FileTable
			fileTable.Width = Unit.Percentage(100D);
			fileTable.GridLines = GridLines.Both;
			fileTable.CellSpacing = this.ListCellspacing;
			fileTable.CellPadding = this.ListCellpadding;
			fileTable.CssClass = this.ListCssClass;
			this.fileTableBind();

			this.Controls.Add(fileTable);
			#endregion
		}

		protected override void OnPreRender(EventArgs e)
		{
			base.OnPreRender(e);

			if (fileTable.Rows.Count < 1)
				fileTable.Visible = false;
		}
	}
}
